home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / mcomm540.zip / COMM.CPP < prev    next >
C/C++ Source or Header  |  1991-01-07  |  10KB  |  262 lines

  1.  
  2. /////////////////////////////////////////////////////////////////////////////
  3. //                                                                         //
  4. //  COMM.CPP -- source for common functions for MCOMM AsyncPort class for  //
  5. //    Zortech C++ 2.0, Turbo C++ 1.0.                                      //
  6. //    Compiler specific code:  MK_FP, SPTR (true if NEAR data), farmalloc  //
  7. //                                                                         //
  8. //    Mike Dumdei,  6 Holly Lane,  Texarkana TX  75503    (c) 1989,1990    //
  9. //                                                                         //
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #include "comm.hpp"
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <dos.h>
  16.  
  17. #if defined(__TURBOC__)
  18.   #include <alloc.h>
  19.   #if (__TINY__ || __SMALL__ || __MEDIUM__)
  20.     #define SPTR 1
  21.   #endif
  22. #endif
  23.  
  24. /////////////////////////////////////////
  25. //  Default ring buffer size variables //
  26. /////////////////////////////////////////
  27. int AsyncPort::DefRxBufSz = 1024;   // 1K receive buffer
  28. int AsyncPort::DefTxBufSz = 1024;   // 1K transmit buffer
  29. int AsyncPort::DefMemType = 0;      // default to NEAR, NZ to default to FAR
  30.  
  31. /////////////////////////////////////////
  32. //  Constructor - Simple               //
  33. //    Presets port variables to 0      //
  34. //://////////////////////////////////////
  35. AsyncPort::AsyncPort()
  36. {
  37.     memset((void *)this, '\0', sizeof(AsyncPort));
  38. }
  39.  
  40. /////////////////////////////////////////
  41. //  Constructor - Allocs ring buffers  //
  42. //    Presets port variables to 0      //
  43. //    Allocates ring buffers           //
  44. //://////////////////////////////////////
  45. AsyncPort::AsyncPort(int RxBufSz, int TxBufSz, int UseFarMem)
  46. {
  47.     memset((void *)this, '\0', sizeof(AsyncPort));
  48.     AllocBuffers(RxBufSz, TxBufSz, UseFarMem);
  49. }
  50.  
  51. /////////////////////////////////////////
  52. //  Destructor                         //
  53. //    If necessary, calls Close and    //
  54. //    frees ring buffer memory.        //
  55. //://////////////////////////////////////
  56. AsyncPort::~AsyncPort()
  57. {
  58.     if (HdlrUsed != '\0')           // true if port not closed yet
  59.         Close();
  60. }
  61.  
  62. /////////////////////////////////////////
  63. //  Open Port - Detailed parameters    //
  64. //    Initializes port for interrupt   //
  65. //    driven operation.  Allocates     //
  66. //    default ring buffers if memory   //
  67. //    has not already been allocated.  //
  68. //    If Open fails default buffers    //
  69. //    are automatically deallocated.   //
  70. //    User defined buffers are not     //
  71. //    automatically deallocated.       //
  72. //://////////////////////////////////////
  73. int AsyncPort::Open(int ComBase, int IRQNbr, int InterruptVctr, char *Params)
  74. {
  75.     int rval;
  76.     int defbuffers = 0;
  77.  
  78.     if (!RingSeg && !RingOfst)          // if ring buffers not allocated,
  79.     {                                   // use defaults
  80.         AllocBuffers(DefRxBufSz, DefTxBufSz, DefMemType);
  81.         defbuffers = 1;
  82.     }
  83.      // open the port
  84.     rval = async_open(this, ComBase, IRQNbr, InterruptVctr, Params);
  85.     if (rval != R_OK && defbuffers == 1)     // if port open failed & default
  86.         FreeBuffers();                       // buffers, free default buffers
  87.     return (rval);                      // return port open result
  88. }
  89.  
  90. /////////////////////////////////////////
  91. //  Open Port -  COM1/COM2 abbrev      //
  92. //    Short method to open either COM1 //
  93. //    or COM2.  Calls detailed Open    //
  94. //    after selecting port address,    //
  95. //    irq, and interrupt vector.       //
  96. //://////////////////////////////////////
  97. int AsyncPort::Open(int ComN, char *Params)
  98. {
  99.     int base, irq, vector;
  100.  
  101.     if (ComN == COM1)
  102.         base = 0x3f8, irq = IRQ4, vector = VCTR4;
  103.     else if (ComN == COM2)
  104.         base = 0x2f8, irq = IRQ3, vector = VCTR3;
  105.     else
  106.         return R_NOPORT;
  107.     return (Open(base, irq, vector, Params));
  108. }
  109.  
  110. /////////////////////////////////////////
  111. //  Close port - No parameters         //
  112. //    Resets port to the state it was  //
  113. //    in prior to being opened.  Frees //
  114. //    ring buffer memory.              //
  115. //://////////////////////////////////////
  116. int AsyncPort::Close()
  117. {
  118.     int rval = async_close(this);   // call low level function to close port
  119.     if (rval == R_OK)               // free ring buffer memory if closed OK
  120.         FreeBuffers();
  121.     return rval;
  122. }
  123.  
  124. /////////////////////////////////////////
  125. //  Close port - Force DTR/RTS         //
  126. //    Manipulates class variable that  //
  127. //    'remembers' initial port DTR or  //
  128. //    RTS setting then calls normal    //
  129. //    Close to close the port and free //
  130. //    ring buffer memory.              //
  131. //://////////////////////////////////////
  132. int AsyncPort::Close(int DTR, int RTS)
  133. {
  134.     if (DTR != 0)                   // if ZR, close with DTR in pre-open state
  135.     {
  136.         if (DTR > 0)                // if > ZR, force DTR to remain high
  137.             OldMCR |= B_DTR;
  138.         else
  139.             OldMCR &= ~B_DTR;       // if < ZR, force DTR to go low
  140.     }
  141.     if (RTS != 0)                   // if ZR, close with RTS in pre-open state
  142.     {
  143.         if (RTS > 0)                // if > ZR, force RTS to remain high
  144.             OldMCR |= B_RTS;
  145.         else
  146.             OldMCR &= ~B_RTS;       // if < ZR, force RTS to go low
  147.     }
  148.     return Close();
  149. }
  150.  
  151. /////////////////////////////////////////
  152. //  Set XON/XOFF trip levels           //
  153. //    Returns R_OK (0) if success, or  //
  154. //    NZ if invalid parameters.  The   //
  155. //    Xon/Xoff 'Levels' are for bytes  //
  156. //    free in the buffer, therefore,   //
  157. //    the XoffLevel must be less than  //
  158. //    the XonLevel.  The Repeat level  //
  159. //    is the number of bytes that will //
  160. //    be accepted after sending an     //
  161. //    Xoff before sending a 2nd Xoff.  //
  162. //://////////////////////////////////////
  163. int AsyncPort::XTrip(int XoffLevel, int XonLevel, int RepeatLevel)
  164. {
  165.     if (XoffLevel >= XonLevel)
  166.         return (-1);
  167.     XoffTrip = XoffLevel;
  168.     XonTrip = XonLevel;
  169.     XTxRptInit = RepeatLevel;
  170.     return 0;
  171. }
  172.  
  173. /////////////////////////////////////////
  174. //  Transmit a C style string          //
  175. //    Returns bytes left available in  //
  176. //    transmit ring buffer.            //
  177. //://////////////////////////////////////
  178. int AsyncPort::Tx(char *String)
  179. {
  180.     return (async_txblk(this, String, strlen(String)));
  181. }
  182.  
  183. /////////////////////////////////////////
  184. //  AllocBuffers                       //
  185. //    Function to allocate ring buffer //
  186. //    memory.  Returns 1 if success,   //
  187. //    0 if memory already allocated or //
  188. //    no memory available.             //
  189. //://////////////////////////////////////
  190. int AsyncPort::AllocBuffers(int RxBufSz, int TxBufSz, int UseFarMem)
  191. {
  192.     unsigned long memptr;
  193.     int memsize = RxBufSz + TxBufSz;
  194.  
  195.     if (RingSeg || RingOfst)
  196.         return 0;                   // don't alloc if already allocated
  197.  
  198. #if SPTR  ////////////////////////////////////
  199.           //  SMALL OR MEDIUM MEMORY MODEL  //
  200.           ////////////////////////////////////
  201.     if (UseFarMem != 0)
  202.     {                               // if ring buffers in FAR mem
  203.         memptr = (unsigned long)farmalloc(memsize);
  204.         Stat3 |= (char)B_FARBUFFER;
  205.     }
  206.     else                            // if ring buffers in NEAR mem
  207.         memptr = (unsigned long)(unsigned int)new char[memsize];
  208.  
  209. #else     /////////////////////////////////////
  210.           //  LARGE OR COMPACT MEMORY MODEL  //
  211.           /////////////////////////////////////
  212.     memptr = (unsigned long)new char[memsize];
  213.  
  214. #endif    ////////////////////////////////////
  215.           //    END MODEL SPECIFIC CODE     //
  216.           ////////////////////////////////////
  217.     RxSize = RxBufSz;               // receive buffer size
  218.     TxSize = TxBufSz;               // transmit buffer size
  219.     RingSeg = (int)(memptr >> 16);  // seg of allocated memory (0 if NEAR)
  220.     RingOfst = (int)memptr;         // offset of allocated memory
  221.     if (memptr == 0L)
  222.         return 0;                   // return 0 if no memory available
  223.     return 1;                       // return 1, had some memory
  224. }
  225.  
  226. /////////////////////////////////////////
  227. //  FreeBuffers                        //
  228. //    Function to release ring buffer  //
  229. //    memory.  Returns 1 if success,   //
  230. //    0 if port not closed or no mem-  //
  231. //    ory to free.                     //
  232. //://////////////////////////////////////
  233. int AsyncPort::FreeBuffers()
  234. {
  235.     if ((!RingSeg && !RingOfst) || (HdlrUsed != '\0'))
  236.         return 0;                   // exit if port busy or nothing to free
  237.  
  238. #if SPTR  ////////////////////////////////////
  239.           //  SMALL OR MEDIUM MEMORY MODEL  //
  240.           ////////////////////////////////////
  241.     if (Stat3 & (char)B_FARBUFFER)
  242.     {                               // if FAR memory was allocated
  243.         farfree(MK_FP(RingSeg, RingOfst));
  244.         Stat3 &= (char)~B_FARBUFFER;
  245.     }
  246.     else
  247.         delete (char *)RingOfst;    // if NEAR memory was allocated
  248.  
  249. #else     /////////////////////////////////////
  250.           //  LARGE OR COMPACT MEMORY MODEL  //
  251.           /////////////////////////////////////
  252.     delete MK_FP(RingSeg, RingOfst);
  253.  
  254. #endif    ////////////////////////////////////
  255.           //    END MODEL SPECIFIC CODE     //
  256.           ////////////////////////////////////
  257.     RingSeg = RingOfst = 0;         // show ring buffers not allocated
  258.     return 1;
  259. }
  260.  
  261.  
  262.